
changequote([,])

define([last_id], 0)
define([next_id],[define([last_id],incr(last_id))last_id])

define([anon_prefix],anon_$1)
define([anon],[anon_prefix(next_id)])

define([patch_vca],[
# 1:id, 2:name, 3:out, 4:amp, 5:in
ifelse([$1],,,[
# id is required
	module	mult patched_vca_$1
	init	patched_vca_$1 count 2

	ifelse([$5],,,[ # if in is defined
		patch	patched_vca_$1:1 $5
	])
	ifelse([$4],,,[ # if amp is defined
		patch	patched_vca_$1:2 $4
	])
	ifelse([$3],,,[ # if out is defined
		patch	$3 patched_vca_$1:out
	])
	define(patched_vca_$1_in, patched_vca_$1:1)
	define(patched_vca_$1_amp, patched_vca_$1:2)
	define(patched_vca_$1_out, patched_vca_$1:out)

	ifelse([$2],,,[ # if name is defined, create the aliases
		define($2_in,patched_vca_$1_in)
		define($2_amp,patched_vca_$1_amp)
		define($2_out,patched_vca_$1_out)
	])
])
])

define([patch_pos],[ # map a -1 to 1 signal to 0 to 1
# 1:id, 2:name, 3:out, 4:amp, 5:in
ifelse([$1],,,[
# id is required
	module proc patched_pos_$1
	define([patched_pos_$1_in], patched_pos_$1:in)
	patch patched_pos_$1:amp .5
	patch patched_pos_$1:off .5
	ifelse([$5],,,[
		patch patched_pos_$1_in $5
	])
	ifelse([$4],,[ # if amp is not defined
		define(patched_pos_$1_out, patched_pos_$1:out)
	],[ # else if amp is defined
		patch_vca(anon,patched_pos_outa_$1,,$4,patched_pos_$1:out)
		define(patched_pos_$1_out, patched_pos_outa_$1_out)
	])

	ifelse([$3],,,[ # if an output was specified, patch it here
		patch	$3 patched_pos_$1_out
	])

	ifelse([$2],,,[ # if a name was specified, create the aliases
		define($2_in, patched_pos_$1_in)
		define($2_out, patched_pos_$1_out)
	])
])
])

define([patch_mult_r],[
# 1:mult, ...:inputs
ifelse([$1],,,[
# mult is required
	ifelse($2,,,[ # patch this input only if it is defined
		patch	$1:eval($# - 1) $2
	])
	ifelse($#,2,,[ # recurse only if there are args left
		patch_mult_r($1,shift(shift($*)))
	])
])
])

define([patch_mult],[
# 1:id, 2:name, 3:out, 4:amp, ...:inputs
ifelse([$1],,,[
# id is required
ifelse(eval($# < 5),1,,[
# there must be at least one input

	module	mult patched_mult_$1
	init	patched_mult_$1 count eval($# - 4)
	patch_mult_r(patched_mult_$1, shift(shift(shift(shift($*)))))

	ifelse([$4],,[ # if amp is not defined
		define(patched_mult_$1_out, patched_mult_$1:out)
	],[ # else if amp is defined
		patch_vca(anon,patched_mult_outa_$1,,$4,patched_mult_$1:out)
		define(patched_mult_$1_out, patched_mult_outa_$1_out)
	])

	ifelse([$3],,,[ # if an output was specified, patch it here
		patch	$3 patched_mult_$1_out
	])

	ifelse([$2],,,[ # if a name was specified, create the aliases
		define($2_out, patched_mult_$1_out)
	])
])
])
])

define([patch_mixer_r],[
# 1:mixer, ...:inputs
ifelse([$1],,,[
# mixer is required
	ifelse($2,,,[ # patch this input only if it is defined
		patch	$1:eval($# - 1) $2
	])
	ifelse($#,2,,[ # recurse only if there are args left
		patch_mixer_r($1,shift(shift($*)))
	])
])
])

define([patch_mixer],[
# 1:id, 2:name, 3:out, 4:amp, ...:inputs
ifelse([$1],,,[
# id is required
ifelse(eval($# < 5),1,,[
# there must be at least one input

	module	add patched_mixer_$1
	init	patched_mixer_$1 count eval($# - 4)
	patch_mixer_r(patched_mixer_$1, shift(shift(shift(shift($*)))))

	ifelse([$4],,[ # if amp is not defined
		define(patched_mixer_$1_out, patched_mixer_$1:out)
	],[ # else if amp is defined
		patch_vca(anon,patched_mixer_outa_$1,,$4,patched_mixer_$1:out)
		define(patched_mixer_$1_out, patched_mixer_outa_$1_out)
	])

	ifelse([$3],,,[ # if an output was specified, patch it here
		patch	$3 patched_mixer_$1_out
	])

	ifelse([$2],,,[ # if a name was specified, create the aliases
		define($2_out, patched_mixer_$1_out)
	])
])
])
])

define([patch_oscil],[ 
# 1:id, 2:name, 3:out, 4:amp, 5:freq, 6:phase, 7:function_in 8:function_out
ifelse([$7],,,[ifelse([$8],,,[ifelse([$1],,,[
# id, function_in, and function_out are required

	define(patched_oscil_$1_freq, patched_oscil_ph_$1:frequency)
	define(patched_oscil_$1_phase, patched_oscil_ph_$1:phase)
	define(patched_oscil_$1_phasor_out, patched_oscil_ph_$1:out)

	module	phasor patched_oscil_ph_$1

	ifelse([$5],,,[ # if frequency is defined
		patch	patched_oscil_$1_freq $5
	])
	ifelse([$6],,,[ # if phase is defined
		patch	patched_oscil_$1_phase $6
	])

	patch $7 patched_oscil_$1_phasor_out

	ifelse([$4],,[ # if amp is not defined
		define(patched_oscil_$1_out, $8)
	],[ # else if amp is defined
		patch_vca(anon,patched_oscil_outa_$1,,$4,$8)
		define(patched_oscil_$1_out, patched_oscil_outa_$1_out)
	])

	ifelse([$3],,,[ # if an output was specified, patch it here
		patch	$3 patched_oscil_$1_out
	])

	ifelse([$2],,,[ # if a name was specified, create the aliases
		define($2_freq, patched_oscil_$1_freq)
		define($2_phase, patched_oscil_$1_phase)
		define($2_phasor_out, patched_oscil_$1_phasor_out)
		define($2_out, patched_oscil_$1_out)
	])

])])])
])

define([patch_oscil_cos],[
# 1:id, 2:name, 3:out, 4:amp, 5:freq, 6:phase
ifelse([$1],,,[
# id is required
	module	cos	patched_oscil_cos_$1
	patch_oscil($*, patched_oscil_cos_$1:in, patched_oscil_cos_$1:out)
])
])

define([patch_out_mono],[
# 1:id, 2:name, 3:out, 4:amp, 5:in
# nothing is required
# id is allowed but redundant
# out is ignored but included for consistency
	ifelse([$1],,,[
		define([patched_output_$1], [out_0:1])
	])
	module	shortout out_0
	init	out_0 count 1
	ifelse([$4],,[ # if amp is not defined
		define([patched_output], [out_0:1])
		ifelse([$5],,,[ # if in is defined, patch it up
			patch	patched_output $5
		])
	], [ # if amp is defined
		define([patched_output], outa_0_out)
		patch_vca(anon,[outa_0],out_0:1, $4, $5)
	])
	ifelse([$2],,,[ # if name is defined, create the aliases
		define($2,patched_output)
	])

])

define([patch_out_left],[
# 1:id, 2:name, 3:out, 4:amp, 5:in
# nothing is required
# id is allowed but redundant
# out is ignored but included for consistency
	ifelse([$1],,,[
		define([patched_output_left_$1], [out_0:1])
	])
	ifelse(is_out_0,1,,[
		module	shortout out_0
		init	out_0 count 2
		define([is_out_0],1)
	])
	ifelse([$4],,[ # if amp is not defined
		define([patched_output_left], [out_0:1])
		ifelse([$5],,,[ # if in is defined, patch it up
			patch	patched_output_left $5
		])
	], [ # if amp is defined
		define([patched_output_left], outa_left_0_out)
		patch_vca(anon,[outa_left_0],out_0:1, $4, $5)
	])
	ifelse([$2],,,[ # if name is defined, create the aliases
		define($2,patched_output_left)
	])

])

define([patch_out_right],[
# 1:id, 2:name, 3:out, 4:in, 5:amp
# nothing is required
# id is allowed but redundant
# out is ignored but included for consistency
	ifelse([$1],,,[
		define([patched_output_right_$1], [out_0:1])
	])
	ifelse(is_out_0,1,,[
		module	shortout out_0
		init	out_0 count 2
		define([is_out_0],1)
	])
	ifelse([$4],,[ # if amp is not defined
		define([patched_output_right], [out_0:2])
		ifelse([$5],,,[ # if in is defined, patch it up
			patch	patched_output_right $5
		])
	], [ # if amp is defined
		define([patched_output_right], outa_right_0_out)
		patch_vca(anon,[outa_right_0],out_0:2, $4, $5)
	])
	ifelse([$2],,,[ # if name is defined, create the aliases
		define($2,patched_output_right)
	])

])
